package com.xstudio.pvzreborn.utils.registry;

import com.xstudio.pvzreborn.block.BlockManager;
import com.xstudio.pvzreborn.event.custom.PVZRegistryEvent;
import com.xstudio.pvzreborn.event.custom.PVZRegistryEvent.Kind;
import com.xstudio.pvzreborn.utils.registry.holder.BlockHolder;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockBehaviour.Properties;
import net.minecraftforge.registries.RegistryObject;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.function.Function;

public class BlockRegistrationHelper extends RegistrationHelper<Properties, Block> {

    private final ItemRegistrationHelper helper;
    /**
     * 存有将要注册的 BlockItem
     */
    private final Map<String, Function<RegistryObject<? extends Block>, RegistrationAction<Item.Properties, BlockItem>>> blockItemMap;

    public BlockRegistrationHelper(String blockGroupName, String itemGroupName, RegistrationAction<Properties, Block> defaultRegistryAction, boolean orderly) {
        super(blockGroupName, orderly ? new LinkedHashMap<>() : new HashMap<>(), defaultRegistryAction);
        this.helper = new ItemRegistrationHelper(itemGroupName, orderly).setRegisteringBlockItem();
        this.blockItemMap = orderly ? new LinkedHashMap<>() : new HashMap<>();
    }

    public BlockRegistrationHelper(String groupName) {
        this(groupName, null, null, false);
    }

    @Override
    public BlockRegistrationHelper addElement(String name, RegistrationAction<Properties, ? extends Block> supplier) {
        registry.put(name, new BlockHolder(name, supplier));
        previousName = name;
        return addBlockItemElement();
    }

    /**
     * 添加自定义的 BlockItem
     *
     * @param function 自定义的 BlockItem 的注册行为
     * @return this
     */
    public BlockRegistrationHelper addBlockItemElement(Function<RegistryObject<? extends Block>, RegistrationAction<Item.Properties, BlockItem>> function) {
        if (previousName != null) {
            blockItemMap.put(previousName, function);
            ((BlockHolder) registry.get(previousName)).setDoNotRegisterBlockItemNow();
        }
        return this;
    }

    /**
     * 删除对应的 BlockItem
     *
     * @return this;
     */
    public BlockRegistrationHelper removeBlockItemElement() {
        if (previousName != null) {
            blockItemMap.remove(previousName);
        }
        return this;
    }

    @Override
    public BlockRegistrationHelper properties(Properties properties) {
        super.properties(properties);
        return this;
    }

    @Override
    public BlockRegistrationHelper addElement(String name) {
        super.addElement(name);
        return this;
    }

    @Override
    public void register() {
        registry.forEach((blockName, holder) -> {
            PVZRegistryEvent.Pre<Block> pre = new PVZRegistryEvent.Pre<>(Kind.Block, Block.class, blockName, groupName, holder.getSupplier());
            if (!pre.postModBus()) {
                RegistryObject<? extends Block> block = BlockManager.BLOCK_REGISTER.register(blockName, pre.getSupplier());
                if (blockItemMap.containsKey(blockName)) {
                    helper.addElement(blockName, blockItemMap.get(blockName).apply(block));
                }
                new PVZRegistryEvent.Post<>(Kind.Block, Block.class, blockName, groupName, block).postModBus();
            }
        });
        helper.register();
    }

    /**
     * 添加默认的 BlockItem
     *
     * @return this;
     */
    private BlockRegistrationHelper addBlockItemElement() {
        return addBlockItemElement((block) -> (blockItemName, properties) -> () -> new BlockItem(block.get(), properties));
    }

}
